<template>
  <div>
    <Save-Organization
      ref="save"
      @refresh="fetchTreeData"
      @create-org="createOrg"
    />
    <a-select
      v-model="keywordsValue"
      class="margin-bottom-10"
      :loading="loading"
      allow-search
      allow-clear
      :data="treeData"
      :placeholder="placeholder"
      :multiple="multiple"
      @search="fetchData"
      @change="handleSelectChange"
    >
      <a-option v-for="item in treeData" :key="item.id" :value="item.id"
        >{{ item.name }}
      </a-option></a-select
    >
    <a-tree
      ref="treeRef"
      v-model:expanded-keys="expandedKeys"
      :default-selected-keys="defaultSelectedKeys"
      :field-names="{ key: 'id', title: 'name' }"
      style="width: 100%; height: 500px; overflow-y: auto"
      :loading="loading"
      :data="renderTreeData"
      block-node
      @select="handleClickTreeNode"
    >
      <template v-if="isEdit" #extra="nodeData">
        <IconPlus
          style="
            position: absolute;
            top: 10px;
            right: 28px;
            color: #3370ff;
            font-size: 12px;
          "
          @click="() => handleIconClick('add', nodeData)"
        />
        <a-popconfirm
          :content="$t('operations.popConfirm.delete')"
          type="error"
          @ok="handleIconClick('del', nodeData)"
        >
          <icon-delete
            style="
              position: absolute;
              top: 10px;
              right: 8px;
              color: red;
              font-size: 12px;
            "
          />
        </a-popconfirm>
      </template>
    </a-tree>
  </div>
</template>

<script lang="ts" setup>
  import { ref, defineProps, defineEmits } from 'vue';
  import useLoading from '@/hooks/loading';
  import {
    delOrg,
    selectOrgById,
    selectOrgByKeywords,
    QueryOrgByKeywordsVO,
    selectRootTreeOrganization,
  } from '@/api/organization';
  import { Message, TreeNodeData } from '@arco-design/web-vue';

  const { loading, setLoading } = useLoading();
  const generateFormModel = () => {
    return {
      address: '',
      adminer: '',
      code: '',
      email: '',
      name: '',
      organzationLeader: '',
      organzationTopLeader: '',
      phone: '',
      postCode: '',
      simpleName: '',
      tenantId: '',
      sysInnerFlag: '0',
      orgName: '',
      tenantStatusEnum: '1',
    };
  };
  const props = defineProps({
    placeholder: {
      type: String,
      default: () => {
        return '请输入关键字查询组织机构';
      },
    },
    isEdit: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
    multiple: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
    allowSearch: {
      type: Boolean,
      default: () => {
        return true;
      },
    },
    allowClear: {
      type: Boolean,
      default: () => {
        return true;
      },
    },
    disable: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
    treeCheckStrictly: {
      type: Boolean,
      default: () => {
        return true;
      },
    },
    isDefaultChecked: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
    tissueType: {
      type: String,
      default: () => {
        return '';
      },
    },
  });
  const keywordsValue = ref('');
  const treeData = ref<QueryOrgByKeywordsVO[]>([]);
  const renderTreeData = ref<TreeNodeData[]>([]);
  const save = ref();
  const treeRef = ref();
  const expandedKeys = ref<any[]>([]);
  const defaultSelectedKeys = ref<any[]>([]);
  const fetchData = async (keywords: any) => {
    setLoading(true);
    try {
      const { data } = await selectOrgByKeywords(keywords);
      treeData.value = data;
    } catch (err) {
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };

  const emit = defineEmits(['select']);

  const fetchTreeData = async () => {
    setLoading(true);
    try {
      const { data } = await selectRootTreeOrganization();
      renderTreeData.value = data;
      const firstItem = renderTreeData.value[0] as { id: string | number };
      expandedKeys.value.push(firstItem.id);
      if (props.isDefaultChecked) {
        defaultSelectedKeys.value.push(firstItem.id);
        emit('select', firstItem);
      }
    } catch (error) {
      // err
    } finally {
      setLoading(false);
    }
  };

  const createOrg = (val: { parentId: string[] }) => {
    expandedKeys.value.push(val.parentId);
    fetchTreeData();
  };

  const handleSelectChange = (val: any) => {
    // 关键词检索中的对象
    const obj: { parentIds: string[] } = treeData.value.filter(
      (item) => item.id === val
    )[0];
    const excludeIds = obj.parentIds.filter(
      (item) => !expandedKeys.value.includes(item)
    );
    expandedKeys.value = expandedKeys.value.concat(excludeIds);
  };

  const handleIconClick = (type: string, nodeData: any, obj?: any) => {
    switch (type) {
      case 'add':
        obj = generateFormModel();
        save.value.handleChangeVisible({
          parentId: nodeData.id,
          parentName: nodeData.name,
          sysInnerFlag: obj.sysInnerFlag,
          tenantStatusEnum: obj.tenantStatusEnum,
        });
        break;
      case 'del':
        delOrg(nodeData.id).then(() => {
          Message.success('操作成功');
          treeData.value = treeData.value.filter(
            (item) => item.id !== nodeData.id
          );
          fetchTreeData();
        });
        break;
      case 'edit':
        selectOrgById(nodeData.id).then((res) => {
          save.value.handleChangeVisible(res.data);
        });
        break;
      default:
        break;
    }
  };

  const handleClickTreeNode = async (
    selectedKeys: (string | number)[],
    data: {
      selected?: boolean | undefined;
      selectedNodes: TreeNodeData[];
      node?: any;
      e?: Event | undefined;
    }
  ) => {
    const { node } = data; // 获取selectedNodes.node
    if (node) {
      emit('select', node);
    }
  };
  fetchData(keywordsValue.value);
  fetchTreeData();
</script>

<style lang="less" scoped>
  .margin-bottom-10 {
    margin-bottom: 10px;
  }
</style>
